
package fss.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * This class implements the utility to serialize an object to a file,
 * and also revert the file back into an object
 * @author hieu
 */
public class SerializableUtils
{
  /**
   * Deserialize a file back into an object
   * @param aFileName Path of the file name
   * @return object if deserialize successfully, otherwise return null
   */
  public static Object deserializeObject(String aFileName)
  {
    Object tReturn = null;
    FileInputStream tFileInputStream = null;
    ObjectInputStream tObjectInputStream = null;
    try
    {
      tFileInputStream = new FileInputStream(new File(aFileName));
      tObjectInputStream = new ObjectInputStream(tFileInputStream);
      tReturn = tObjectInputStream.readObject();
    }
    catch (FileNotFoundException aEx)
    {
      System.out.println("File not found. Unable to load state.");
    }
    catch (Exception aEx)
    {} finally {
        if(tFileInputStream != null)
            try {
                tFileInputStream.close();
            } catch (IOException e) {
                // ignore
            }
        if(tObjectInputStream != null)
            try {
                tObjectInputStream.close();
            } catch (IOException e) {
                // ignore
            }
    }
    return tReturn;
  }

  /**
   * Serialize an object and write it to a file
   * @param aObject the object to be serialized
   * @param aFileName absolute path of the file
   * @return true if the serialize is success, otherwise return false
   */
  public static boolean serializeObject (Object aObject, String aFileName)
  {
    boolean tSuccess = false;
    FileOutputStream tFileOutputStream = null;
    ObjectOutputStream tObjectOutputStream = null;
    try
    {
      if (aObject instanceof Serializable)
      {
        tFileOutputStream =
          new FileOutputStream(new File(aFileName), false);
        tObjectOutputStream =
          new ObjectOutputStream(tFileOutputStream);
        tObjectOutputStream.writeObject(aObject);
        tFileOutputStream.close();
        tSuccess = true;
      }
    }
    catch (IOException aEx)
    {
      tSuccess = false;
    } finally {
        if(tFileOutputStream != null)
            try {
                tFileOutputStream.close();
            } catch (IOException e) {}
        if(tObjectOutputStream != null) {
            try {
                tObjectOutputStream.close();
            } catch (IOException e) {}
        }
    }
    return tSuccess;
  }

  /**
   * UNIT TEST
   */
  private static class TestClass implements Serializable
  {
    public int mNum;
    public String mString;
  }

  public static void main (String[] aArg)
  {
    TestClass before = new TestClass();
    before.mNum = 100;
    before.mString = "Unit Test";
    boolean done = serializeObject(before, "/tmp/test");
    if (done)
    {
      TestClass after = (TestClass) deserializeObject("/tmp/test");
      if (before.mNum == after.mNum &&
          before.mString.equals(after.mString))
      {
        System.out.println ("   ---> Unit test pass.");
      }
      else
      {
        System.out.println ("   ---> Unit test fail.");
      }
    }
  }
}
